# -*- coding: utf-8 -*-
"""
增强版保单EDA分析
新增字段分析：教育水平、职业、婚姻状况、家庭成员、保单类型
"""

try:
    import os
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    import numpy as np
except ImportError:
    print("请先安装依赖库：pip install pandas matplotlib seaborn openpyxl")
    exit()

def enhanced_eda(file_path):
    """执行增强版EDA分析"""
    output_dir = "analysis_figures"
    os.makedirs(output_dir, exist_ok=True)

    try:
        df = pd.read_excel(file_path, engine='openpyxl')
    except Exception as e:
        print(f"文件读取失败: {str(e)}")
        exit()

    # 数据预处理
    df['policy_term_years'] = df['policy_term'].str.extract('(\d+)').astype(int)
    df['policy_duration'] = (pd.to_datetime(df['policy_end_date']) - 
                            pd.to_datetime(df['policy_start_date'])).dt.days / 365
    
    # 创建统一画布（6行3列布局）
    plt.figure(figsize=(24, 30))
    plt.suptitle('保单数据综合分析报告', y=0.99, fontsize=20)
    
    # === 新增字段分析 ===
    # 教育水平分布
    plt.subplot(6, 3, 1)
    edu_order = df['education_level'].value_counts().index
    sns.countplot(y='education_level', data=df, order=edu_order)
    plt.title('教育水平分布')
    
    # 职业分布（取前10）
    plt.subplot(6, 3, 2)
    top_occupations = df['occupation'].value_counts().head(10).index
    sns.countplot(y='occupation', data=df, order=top_occupations)
    plt.title('职业分布Top10')
    
    # 婚姻状况
    plt.subplot(6, 3, 3)
    df['marital_status'].value_counts().plot.pie(autopct='%1.1f%%')
    plt.ylabel('')  # 移除默认的ylabel
    plt.title('婚姻状况分布')
    
    # 家庭成员分布
    plt.subplot(6, 3, 4)
    sns.histplot(df['family_members'], bins=15, kde=True)
    plt.title('家庭成员数量分布')
    
    # 保单类型分析
    plt.subplot(6, 3, 5)
    policy_order = df['policy_type'].value_counts().head(10).index
    sns.countplot(y='policy_type', data=df, order=policy_order)
    plt.title('保单类型Top10')
    
    # === 续保相关分析 ===
    # 教育水平 vs 续保率
    plt.subplot(6, 3, 6)
    edu_renew = df.groupby('education_level')['renewal'].value_counts(normalize=True).unstack()
    edu_renew.sort_values('Yes', ascending=False)['Yes'].plot.barh()
    plt.title('不同教育水平续保率')
    plt.xlabel('续保率')
    
    # 职业 vs 续保率（Top10职业）
    plt.subplot(6, 3, 7)
    occupation_renew = df[df['occupation'].isin(top_occupations)].groupby('occupation')['renewal'].value_counts(normalize=True).unstack()
    occupation_renew['Yes'].sort_values().plot.barh()
    plt.title('Top10职业续保率')
    plt.xlabel('续保率')
    
    # 保单类型 vs 续保率
    plt.subplot(6, 3, 8)
    policy_renew = df.groupby('policy_type')['renewal'].value_counts(normalize=True).unstack()
    policy_renew['Yes'].sort_values(ascending=False).head(10).plot.barh()
    plt.title('Top10保单类型续保率')
    plt.xlabel('续保率')
    
    # 家庭成员 vs 续保
    plt.subplot(6, 3, 9)
    sns.boxplot(x='renewal', y='family_members', data=df)
    plt.title('家庭成员数量与续保关系')
    
    # 保险期限分析
    plt.subplot(6, 3, 10)
    sns.scatterplot(x='policy_term_years', y='premium_amount', hue='renewal', data=df)
    plt.title('保险期限与保费关系')
    
    # 保单持续时间分析
    plt.subplot(6, 3, 11)
    sns.histplot(df, x='policy_duration', hue='renewal', element='step', stat='density')
    plt.title('保单持续时间分布')
    
    # === 新增：在第12号位置添加热力图 ===
    plt.subplot(6, 3, 12)
    numeric_cols = ['age', 'premium_amount', 'family_members', 
                   'policy_term_years', 'policy_duration']
    corr_matrix = df[numeric_cols].corr()
    mask = np.triu(np.ones_like(corr_matrix, dtype=bool))
    sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap="coolwarm",
               mask=mask, linewidths=0.5, cbar_kws={"shrink": 0.8})
    plt.title("数值特征相关性热力图", pad=20)
    
    # === 调整全局布局 ===
    plt.subplots_adjust(left=0.08, right=0.95,
                       bottom=0.05, top=0.95,
                       wspace=0.3, hspace=0.4)
    
    # 统一保存
    plt.savefig(f"{output_dir}/combined_analysis.png", 
               dpi=150, bbox_inches='tight')
    plt.close()  # 关闭画布释放内存
    
    # === 新增：生成文本分析报告 ===
    def generate_text_report(df, file_name="analysis_report.txt"):
        """生成文本分析报告"""
        report = []
        
        # 基础统计
        report.append("=== 基础统计 ===")
        report.append(f"总样本数: {len(df):,}")
        report.append(f"续保率: {df['renewal'].value_counts(normalize=True)['Yes']:.2%}")
        report.append(f"平均年龄: {df['age'].mean():.1f} ± {df['age'].std():.1f} 岁")
        report.append(f"保费中位数: ￥{df['premium_amount'].median():,.0f}")
        report.append(f"平均家庭成员数: {df['family_members'].mean():.1f} 人\n")
        
        # 关键相关性
        report.append("=== 关键相关性 ===")
        report.append("年龄与保费: {:.2f}".format(
            df[['age', 'premium_amount']].corr().iloc[0,1]))
        report.append("保险期限与持续时间: {:.2f}\n".format(
            df[['policy_term_years', 'policy_duration']].corr().iloc[0,1]))
        
        # 续保相关分析
        report.append("=== 续保差异分析 ===")
        for col in ['gender', 'income_level', 'education_level']:
            ratio = df.groupby(col)['renewal'].value_counts(normalize=True).unstack()['Yes']
            report.append(f"{col}续保率差异：{ratio.idxmax()}({ratio.max():.2%}) → {ratio.idxmin()}({ratio.min():.2%})")
        
        # 异常值检测
        report.append("\n=== 异常值提示 ===")
        high_premium = df[df['premium_amount'] > df['premium_amount'].quantile(0.99)]
        if not high_premium.empty:
            report.append(f"检测到{len(high_premium)}条超高保费记录（>￥{high_premium['premium_amount'].min():,.0f}）")
        
        # 写入文件
        with open(file_name, 'w', encoding='utf-8') as f:
            f.write("\n".join(report))
        print(f"分析报告已生成：{file_name}")

    # 在函数末尾调用
    generate_text_report(df)

if __name__ == "__main__":
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    
    enhanced_eda("policy_data.xlsx")